package def

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"sort"
	"strings"
)

func JavaDef(bs []byte, name string) {
	var data interface{}
	err := json.Unmarshal(bs, &data)
	if err != nil {
		log.Fatal(err)
	}
	buf := bytes.NewBuffer([]byte{})
	javaType(buf, "", name, data)
	fmt.Println(string(buf.Bytes()))
}

func javaType(buf *bytes.Buffer, prefix, name string, data interface{}) string {
	switch val_data := data.(type) {
	case string:
		return "String"
	case bool:
		return "Boolean"
	case float64:
		if float64(int64(val_data)) == val_data {
			return "Long"
		}
		return "Double"
	case int64:
		return "Long"
	case []interface{}:
		if len(val_data) > 0 {
			return javaType(buf, prefix, name, val_data[0]) + "[]"
		}
		return "Object[]"
	case map[string]interface{}:
		var keys []string
		for i_k := range val_data {
			keys = append(keys, i_k)
		}
		sort.Strings(keys)

		tmp := "class " + strings.Title(prefix+name) + " {\n"
		for _, i_k := range keys {
			if Is_java_kw(i_k) {
				tmp = tmp + "\t@SerializedName(\"" + i_k + "\")\n"
				tmp = tmp + "\tpublic " + javaType(buf, prefix+name+"_", i_k, val_data[i_k]) + " _" + i_k + ";\n"
			} else {
				tmp = tmp + "\tpublic " + javaType(buf, prefix+name+"_", i_k, val_data[i_k]) + " " + i_k + ";\n"
			}
		}
		tmp = tmp + "}\n"
		buf.WriteString(tmp)

		return "" + strings.Title(prefix+name)
	default:
		return "Object"
	}
}
